Cocos Creator 中动态修改 Layer 的"坑"和"救命稻草"
#游戏 #Cocos Creator问题表现
开发3D角色预览功能时遇到了个”神奇”的问题:
- 需求是把3D角色渲染到2D精灵纹理上
- 为了让预览效果更纯粹,特地设置了相机和渲染节点的 layer 属性
- 但是!动态加载新角色后,啥报错也没有,角色就是倔强地不显示 😅
明明改了 Layer,角色却倔强地不肯显示!经过一番”火眼金睛”的排查,最終发现原来是 Layer 的继承机制在捣鬼,來看一下事件始末。
分析问题
在面对 3D 角色明明修改了 Layer 却倔强不肯显示这一棘手问题时,我展开了全面且细致的分析排查过程,犹如抽丝剥茧般,逐步探寻问题的根源所在。
初步排查
首先,我启用了专业的审查工具,对涉及到的各个节点属性进行了逐一检查。这一环节至关重要,因为节点属性的设置直接关系到角色的显示效果。我仔细核对了可能影响角色显示的属性参数,然而,经过一番严谨的审视,发现所有节点属性看起来都处于正常状态,并没有发现任何明显的异常之处,这使得问题愈发显得神秘莫测。
显示部分排查
接着,我将目光聚焦在了显示部分。毕竟,角色最终是要呈现在屏幕上供玩家预览的,所以显示环节不容有失。我对显示相关的设置、渲染流程等进行了深入的检查,确保从渲染到最终呈现的每一个环节都能正常运作。但令人失望的是,经过这一轮的排查,显示部分也未发现任何能够解释角色为何不显示的问题,这无疑给我的排查工作又增添了几分难度。
加载逻辑排查
随后,我把注意力转移到了加载逻辑上。因为角色是动态加载的,所以加载过程是否顺利、逻辑是否正确对于角色能否正常显示起着关键作用。我对整个加载逻辑进行了全面的梳理,从数据的读取、模型的初始化,到最终在场景中的加载呈现,每一个步骤都经过了反复的验证。然而,经过这一番细致的排查,加载逻辑也被证实是没有任何毛病的,这让我怀疑人生。
关键突破
就在排查工作陷入僵局之时,突然灵光一闪💡,我开始怀疑会不会是 layer 设置方面出现了问题呢?这一想法仿佛为我在黑暗中点亮了一盏明灯,指引着我朝着新的方向去探索。于是,我迅速采取行动,尝试将相机的 visibility 属性改成“全部渲染”。令人惊喜的是,在做出这一改动之后,原本倔强不肯显示的角色竟然乖乖地出现在了屏幕上!这一发现无疑是一个重大的突破,它让我初步确定了问题的大致方向 —— 很可能就是 layer 设置以及与之相关的某些机制在作祟。
解决问题的关键
在确定了问题大概率出在 layer 设置相关方面之后,我便开始了一系列针对性的尝试,旨在找到能够彻底解决问题的有效方法。
初步尝试
首先,我尝试对渲染相机的 visibility 属性进行设置,将其设定为 preview(从一开始就设置的只渲染预览角色部分的layer值)。在动态加载完成模型资源后,手动设置节点的layer与父节点layer相同(默认是与编辑保持prefab资源时候保持一致),我。然而,仅仅进行这一步操作后,虽然角色依然不能够显示,这表明我还需要进一步深入探索解决方案。
关键调整
在经过初步尝试并发现问题并未完全解决之后,我继续深入研究。通过进一步的分析和试验,我发现了一个关键的点 —— 在动态加载完模型后,仅仅设置节点自身的 layer 属性是不够的,还需要手动将节点的 layer 设置为与父节点一致。
模型子节点的 layer 属性也在影响着整个显示效果。只有同时修改才能确保整个角色及其所有相关节点在各种场景下都能稳定且正确地显示。
真是个大坑,同一个模型很容易忽略子节点也需要手动设置的事实,不知道引擎为何要怎么设定~
解决方案:
// 这才是正确的打开方式!
model.layer = layerValue;
model.walk((node) => {
node.layer = layerValue;
return true;
});
通过这段代码,我首先将模型(model)的 layer 属性设置为正确的值(layerValue),然后利用 walk 方法优雅地遍历模型的所有子节点,并将每个子节点的 layer 属性也设置为相同的 layerValue。这样一来,就确保了无论是父节点还是子节点,它们的 layer 属性都能保持一致且正确,从而彻底解决了角色在动态修改 Layer 后不显示的问题。
希望以上对分析问题和解决问题过程的详细阐述,能够帮助其他开发者在遇到类似问题时,能够更加清晰地理解问题所在,并迅速找到有效的解决方案。
注意事项
- 修改节点 layer 时,千万别忘了它的小伙伴(子节点)们!
- 引擎默认不会自动同步父子节点的 layer 属性
- 使用 walk 方法可以优雅地遍历所有子节点 👍